package org.lds.message.center.server.endpoint;

import com.google.protobuf.ByteString;
import com.google.protobuf.ProtocolStringList;
import io.grpc.stub.StreamObserver;
import lombok.RequiredArgsConstructor;
import net.devh.boot.grpc.server.service.GrpcService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.lds.message.center.common.model.request.PublicRequest;
import org.lds.message.center.core.DefaultEndpoint;
import org.lds.message.center.server.common.util.GrpcResultDTOUtil;
import org.lds.message.center.service.grpc.GrpcResultDTO;
import org.lds.message.center.service.grpc.MessageCenterServiceGrpc;
import org.lds.message.center.service.grpc.PublicGrpcRequest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@GrpcService
@RequiredArgsConstructor
public class GrpcEndpoint extends MessageCenterServiceGrpc.MessageCenterServiceImplBase {
    private final DefaultEndpoint defaultEndpoint;


    @Override
    public void common(PublicGrpcRequest request, StreamObserver<GrpcResultDTO> responseObserver) {
        responseObserver.onNext(common(request));
        responseObserver.onCompleted();
    }

    public GrpcResultDTO common(PublicGrpcRequest request) {
        return GrpcResultDTOUtil.toGrpc(defaultEndpoint.common(PublicRequest.builder()
                .request(buildPublicRequest(request))
                .build()));
    }

    private Map<String, List<String>> buildPublicRequest(PublicGrpcRequest request) {
        if (request == null) return null;
        Map<String, PublicGrpcRequest.GrpcRequest> requestMap = request.getRequestMap();
        if (MapUtils.isEmpty(requestMap)) return null;

        Map<String, List<String>> map = new HashMap<>();
        requestMap.forEach((k, v) -> {
            List<String> list = toStringList(v.getRequestList());
            if (CollectionUtils.isNotEmpty(list)) {
                map.put(k, list);
            }
        });

        return map;
    }


    private List<String> toStringList(ProtocolStringList dataList) {
        if (Objects.isNull(dataList)) return null;
        List<ByteString> byteStrings = dataList.asByteStringList();
        if (CollectionUtils.isEmpty(byteStrings)) return null;
        return byteStrings.stream()
                .map(byteString -> byteString.toStringUtf8())
                .collect(Collectors.toList());
    }

}
